home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / louie / robustapply.py < prev    next >
Text File  |  2005-11-30  |  2KB  |  59 lines

  1. """Robust apply mechanism.
  2.  
  3. Provides a function 'call', which can sort out what arguments a given
  4. callable object can take, and subset the given arguments to match only
  5. those which are acceptable.
  6. """
  7.  
  8. def function(receiver):
  9.     """Get function-like callable object for given receiver.
  10.  
  11.     returns (function_or_method, codeObject, fromMethod)
  12.  
  13.     If fromMethod is true, then the callable already has its first
  14.     argument bound.
  15.     """
  16.     if hasattr(receiver, '__call__'):
  17.         # receiver is a class instance; assume it is callable.
  18.         # Reassign receiver to the actual method that will be called.
  19.         c = receiver.__call__
  20.         if hasattr(c, 'im_func') or hasattr(c, 'im_code'):
  21.             receiver = c
  22.     if hasattr(receiver, 'im_func'):
  23.         # receiver is an instance-method.
  24.         return receiver, receiver.im_func.func_code, 1
  25.     elif not hasattr(receiver, 'func_code'):
  26.         raise ValueError(
  27.             'unknown reciever type %s %s' % (receiver, type(receiver)))
  28.     return receiver, receiver.func_code, 0
  29.  
  30.  
  31. def robust_apply(receiver, signature, *arguments, **named):
  32.     """Call receiver with arguments and appropriate subset of named.
  33.     ``signature`` is the callable used to determine the call signature
  34.     of the receiver, in case ``receiver`` is a callable wrapper of the
  35.     actual receiver."""
  36.     signature, code_object, startIndex = function(signature)
  37.     acceptable = code_object.co_varnames[
  38.         startIndex + len(arguments):
  39.         code_object.co_argcount
  40.         ]
  41.     for name in code_object.co_varnames[
  42.         startIndex:startIndex + len(arguments)
  43.         ]:
  44.         if named.has_key(name):
  45.             raise TypeError(
  46.                 'Argument %r specified both positionally '
  47.                 'and as a keyword for calling %r'
  48.                 % (name, signature)
  49.                 )
  50.     if not (code_object.co_flags & 8):
  51.         # fc does not have a **kwds type parameter, therefore 
  52.         # remove unacceptable arguments.
  53.         for arg in named.keys():
  54.             if arg not in acceptable:
  55.                 del named[arg]
  56.     return receiver(*arguments, **named)
  57.  
  58.             
  59.